// 1 导入react
import React from 'react'
import ReactDOM from 'react-dom'

import PropTypes from 'prop-types'
// 引入css文件
import "./index.css"

// 导入图片资源

import img from './img/cat.jpg'

/**
 * render-props和高阶组件
 */


// react 组件复用概述
// 思考:如果两个组件中的部分功能相似或者相同 该如何处理??
// 处理方式: 复用相似的功能 (联想函数封装)
// 复用什么? 1. state 2.操作state方法(组件状态逻辑)
// 两种方式 1. render props模式  2.高阶组件(HOC)
// 注意: 两种方式不是新的API 而是利用React自身特点的编码技巧,演化而成的固定模式(写法)



// 思路分析

// 思路:将要复用的state和操作state的方法封装到一个组建中
// 问题一: 如何改到组件中复用的state
// 在使用组件时,添加一个值为函数的prop ,通过函数参数来获取(需要组件内部实现)
// 问题二：如果渲染任意的UI?
// 使用该函数的返回值作为要渲染的UI内容 (需要组件内部实现)

/**
 * render props 模式
 */

// 使用步骤
// 1. 穿件Mouse组件， 在组件中提供复用的状态逻辑代码 （1.状态,2.操作状态的方法）
// 2. 将要复用的状态作为props.render(state)方法的参数 , 暴露到组件外部
// 3. 使用props.render()的返回值作为渲染的内容



// children 代替render属性

// 注意: 并不是该模式叫 render props 就是必须使用名称为render的prop 实际上可以使用任意名称
// 把prop是一个函数并且告诉组件要渲染什么内容的技术叫做 render props模式
// 推荐:使用children 代理render属性

// 代码优化
// 使用protoType
// 使用componentWillUnmount


class Mouse extends React.Component {

    constructor(props) {
        super(props)
        console.warn("生命周期钩子函数: constructor")
    }

    state = {
        x: 0,
        y: 0,
    }

    // 鼠标移动事件的事件处理程序
    handleMouseMove = (e) => {
        this.setState({
            x: e.clientX,
            y: e.clientY
        })
    }

    // 监听鼠标移动事件
    componentDidMount() {
        window.addEventListener('mousemove', this.handleMouseMove)
    }

    //推荐: 在组件卸载时移除
    componentWillUnmount() {
        window.removeEventListener('mousemove', this.handleMouseMove)
    }
    render() {
        // return this.props.render(this.state)
        // children 模式
        return this.props.children(this.state)
    }

}


// 添加props 校验
Mouse.protoType = {
    children: PropTypes.func.isRequired
}


class App extends React.Component {

    render() {
        return (
            <div>
                {/* <h1>render props 模式</h1> */}
                {/* <Mouse render={(mouse) => {
                    const { x, y } = mouse
                    return (
                        <p>
                            鼠标位置: {x},{y}
                        </p>
                    )
                }} /> */}
                {/* children模式 */}
                <h1>render children 模式</h1>
                <Mouse>
                    {mouse => {
                        return (
                            <p>
                                鼠标位置: {mouse.x},{mouse.y}
                            </p>
                        )
                    }}
                </Mouse>

                {/* 实现猫捉老鼠 */}

                {/* <Mouse render={mouse => {
                    console.log(img)
                    const { x, y } = mouse
                    return (
                        <img src={img}
                            width="200"
                            alt='猫咪'
                            style={{
                                position: 'absolute',
                                top: y - 50,
                                left: x - 100
                            }}
                        />
                    )
                }}>
                </Mouse> */}

                {/* children模式 */}

                <Mouse >
                    {
                        (mouse) => {
                            const { x, y } = mouse
                            return (
                                <img src={img}
                                    width="200"
                                    alt='猫咪'
                                    style={{
                                        position: 'absolute',
                                        top: y - 50,
                                        left: x - 100
                                    }}
                                />
                            )
                        }
                    }
                </Mouse>
            </div>
        )
    }
}

//3 渲染react元素
ReactDOM.render(
    <App />,
    document.getElementById('root'))
